{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Домашнее задание к лекции \"Регулярные выражения\"\n",
    "Внимание! При реализации всех заданий необходимо использовать именно функционал регулярных выражений для обработки текста.\n",
    "\n",
    "## Задание 1\n",
    "\n",
    "Напишите функцию, которая принимает на вход строку и проверяет является ли она валидным транспортным номером (1 буква, 3 цифры, 2 буквы, 2-3 цифры). Обратите внимание, что не все буквы кириллического алфавита используются в транспортных номерах.\n",
    "\n",
    "Если номер валиден, то функция должна возвращать отдельно номер и регион.\n",
    "\n",
    "Примеры работы программы:\n",
    "\n",
    "car_id = 'A222BC96'\n",
    "Результат: Номер A222BС валиден. Регион: 96\n",
    "\n",
    "car_id = 'АБ22ВВ193'\n",
    "Результат: Номер не валиден"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import re\n",
    "from collections import Counter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Номер машины А234ЕК124 валиден. Регион: 124\n",
      "Номер машины Х777ОО179 не валиден.\n"
     ]
    }
   ],
   "source": [
    "def validate_transport_number_t15(number:str)-> (bool, str):\n",
    "    \"\"\"Функция првоеряет валидность транспортного номера с типом 15 \n",
    "    (для легковых, грузовых, грузопассажирских автомобилей, автобусов, автомобильных прицепов и полуприцепов).\n",
    "    Формат корректного транспортного номера: 1 буква, 3 цифры, 2 буквы, 2-3 цифры. Пример: A222BC96.\n",
    "    \n",
    "    Входные параметры:\n",
    "    number -- транспортный номер в формате str\n",
    "    \n",
    "    Выходные параметры: (флаг валидности в формате bool, номер региона в формате str)\n",
    "    \"\"\"\n",
    "    \n",
    "    number = str(number).upper()\n",
    "    \n",
    "    VALID_REGION_NUMBERS = ('1','02','102','702','3','4','5','6',\n",
    "                            '7','8','9','10','11','12','13','113',\n",
    "                            '14','15','16','116','716','17','18',\n",
    "                            '19','21','121','22','122','23','93',\n",
    "                            '123','193','24','84','88','124','25',\n",
    "                            '125','26','126','27','127','28','29',\n",
    "                            '30','31','32','33','34','134','35','36',\n",
    "                            '136','37','38','85','138','39','91','40',\n",
    "                            '41','82','42','142','43','44','45','46',\n",
    "                            '47','147','48','49','50','90','150','190',\n",
    "                            '750','790','51','52','152','53','54','154',\n",
    "                            '55','56','156','57','58','59','81','159',\n",
    "                            '60','61','161','761','62','63','163','763',\n",
    "                            '64','164','65','66','96','196','67','68',\n",
    "                            '69','169','70','71','72','73','173','74',\n",
    "                            '174','774','75','80','76','77','97','99',\n",
    "                            '177','199','197','777','797','799','78',\n",
    "                            '98','178','198','79','82','83','86','186',\n",
    "                            '87','89','92','94','20','95')\n",
    "    \n",
    "    pattern = r'^[АВЕКМНОРСТУХ]\\d{3}[АВЕКМНОРСТУХ]{2}(\\d{2,3})$'\n",
    "    word = re.compile(pattern)\n",
    "    result = word.findall(number)\n",
    "    if len(result) == 0:\n",
    "        region_number = ''\n",
    "    else:\n",
    "        region_number = result[0]\n",
    "    \n",
    "    # Значение региона будет отличным от пустой строки только в том случае, если соблюдено базовое соответствие формату\n",
    "    # В случае базового соотвествия формату требуется проверить номер региона на корректность.\n",
    "    if region_number in VALID_REGION_NUMBERS:\n",
    "        return True, region_number\n",
    "    else:\n",
    "        return False, region_number\n",
    "    \n",
    "    \n",
    "ts_numbers = ('А234ЕК124', 'Х777ОО179')\n",
    "for ts_number in ts_numbers:\n",
    "    tn_is_valid, region_number = validate_transport_number_t15(ts_number)\n",
    "    print(f'Номер машины {ts_number}', f'валиден. Регион: {region_number}' if tn_is_valid else 'не валиден.')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Задание 2\n",
    "\n",
    "Напишите функцию, которая будет удалять все последовательные повторы слов из заданной строки при помощи регулярных выражений."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Сегодня шел большой дождь, было пять часов вечера'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def remove_repeat_words(line:str)->str:\n",
    "    return re.sub(r'(\\b\\w+)\\s\\1', r'\\1', line)\n",
    "line = 'Сегодня Сегодня шел шел большой дождь дождь, было было пять часов вечера вечера'\n",
    "remove_repeat_words(line)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Задание 3\n",
    "\n",
    "Напишите функцию, которая будет возвращать акроним по переданной в нее строке со словами."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NFC\n"
     ]
    }
   ],
   "source": [
    "def make_acronym(words:str)->str:\n",
    "    return ''.join(re.findall(r'(?:\\b\\w)', words)).upper()\n",
    "\n",
    "some_words = 'Near Field Communication'\n",
    "print(make_acronym(some_words))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Задание 4\n",
    "\n",
    "Напишите функцию, которая будет принимать на вход список email-адресов и выводить их распределение по доменным зонам."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gmail.com: 2\n",
      "test.in: 1\n",
      "ya.ru: 2\n",
      "mail.ru: 1\n"
     ]
    }
   ],
   "source": [
    "emails = ['test@gmail.com', 'xyz@test.in', 'test@ya.ru', 'xyz@mail.ru', 'xyz@ya.ru', 'xyz@gmail.com']\n",
    "def print_domen_statistic(emails:list) -> None:\n",
    "    \"\"\"\n",
    "    Функция печатает статистику используемых доменов в email-адресах.\n",
    "    \n",
    "    Входные параметры:\n",
    "    emails -- список email-адресов\n",
    "    \"\"\" \n",
    "    for domen, counter in Counter(re.findall(r'@(\\w+\\.\\w+)','\\n'.join(emails))).items():\n",
    "        print(f'{domen}: {counter}')\n",
    "\n",
    "print_domen_statistic(emails)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Задание 5 (необязательное)\n",
    "\n",
    "Напишите функцию, которая будет подсчитывать сколько слов начинается на гласные, а сколько на согласные буквы в тексте (текст может быть написан как с использованием букв кириллицы, так и латиницы)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Слов на гласные буквы: 9\n",
      "Слов на согласные буквы: 21\n"
     ]
    }
   ],
   "source": [
    "def counting_letters_type(text:str) -> None:\n",
    "    \"\"\" Функция выводит на печать количество слов, которые начинаются на глассные и согласные буквы.\n",
    "    \n",
    "    Входные параметры:\n",
    "    text -- текст для анализа\n",
    "    \"\"\"\n",
    "    \n",
    "    vowels = len(re.findall(r'\\b[АЕЁИОУЫЭЮЯAEIOUY]', text, flags=re.IGNORECASE))\n",
    "    consonants = len(re.findall(r'\\b[БВГДЖЗКЛМНПРСТФХЦЧШЩЪBCDFGHJKLMNPQRSTVWXZ]', text, flags=re.IGNORECASE))\n",
    "    print(f'Слов на гласные буквы: {vowels}\\nСлов на согласные буквы: {consonants}')\n",
    "    \n",
    "text = \"\"\"\n",
    "Эталонной реализацией Python является интерпретатор CPython, поддерживающий большинство \n",
    "активно используемых платформ. Он распространяется под свободной лицензией Python Software Foundation License, \n",
    "позволяющей использовать его без ограничений в любых приложениях, включая проприетарные.\n",
    "\"\"\"\n",
    "counting_letters_type(text)\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Задание 6 (необязательное)\n",
    "\n",
    "Напишите функцию, которая будет проверять номер сотового телефона на валидность, если он валиден, то переводить его в формат: +7-xxx-xxx-xx-xx"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "+7 955 555-55-55 -> +7-955-555-55-55\n",
      "8(955)555-55-55 -> +7-955-555-55-55\n",
      "+7 955 555 55 55 -> +7-955-555-55-55\n",
      "7(955) 555-55-55 -> +7-955-555-55-55\n",
      "Номер 423-555-55-5555 не валиден\n",
      "Номер 123-456-789 не валиден\n"
     ]
    }
   ],
   "source": [
    "def convert_phone_format(phone:str) -> str:\n",
    "    \"\"\"Функция конвертации номера телефона в формат +7-xxx-xxx-xx-xx\n",
    "    \n",
    "    Входные параметры:\n",
    "    phone -- номер телефона тип str\n",
    "    \n",
    "    Выходные результаты: str, номер телефона в формате +7-xxx-xxx-xx-xx.\n",
    "    Пустая строка, если формат телефона не поддерживается\n",
    "    \"\"\"\n",
    "    \n",
    "    pattern = r'\\+?[78][\\(\\s-]*(\\d{3})[\\)\\s-]*(\\d{3})[\\s-]*(\\d\\d)[\\s-]*(\\d\\d)'\n",
    "    search_result = re.findall(pattern, phone)\n",
    "    if len(search_result) == 0:\n",
    "        return ''\n",
    "    return '+7-{}-{}-{}-{}'.format(*search_result[0])\n",
    "\n",
    "\n",
    "phone_numbers = (\n",
    "    '+7 955 555-55-55',\n",
    "    '8(955)555-55-55',\n",
    "    '+7 955 555 55 55',\n",
    "    '7(955) 555-55-55',\n",
    "    '423-555-55-5555',\n",
    "    '123-456-789')\n",
    "\n",
    "for phone_number in phone_numbers:\n",
    "    phone_format = convert_phone_format(phone_number)\n",
    "    if phone_format:\n",
    "        print(f'{phone_number} -> {phone_format}')\n",
    "    else:\n",
    "        print(f'Номер {phone_number} не валиден')\n",
    "        "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
